use std::{ops::Deref, rc::Rc};

// 自定义Box
#[derive(Debug)]
struct MyBox<T>(T); // 元组结构体

impl<T> MyBox<T> {
    fn new(x: T) -> MyBox<T> {
        MyBox(x)
    }
}

impl<T> Deref for MyBox<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.0
    }
}

impl<T> Drop for MyBox<T> {
    fn drop(&mut self) {
        println!("drop....")
    }
}

fn do_something(str: &str) {
    // do something...
}

// ==============

// 使用装箱定义递归数据结构
// 使得该结构占用空间内确定
enum List {
    Cons(i32, Box<List>),
    Nil(),
}
/* enum List1<'a> {
    Cons(i32, &'a List1<'a>),
    Nil(),
} */

// 多重所有权
// Rc只能被用于单线程场景
enum Node {
    Cons(i32, Rc<Node>),
    Nil(),
}

fn main() {
    let x = MyBox::new("hi");
    // 自动调用了 deref方法 返回引用, 再使用*进行解引用
    // 使得MyBox和普通引用一样
    assert_eq!("hi", *x);

    // Box -> String -> str -> &str
    do_something(&((*(*x))));
    // Box -> String, 再对字符串取切片
    do_something(&(*x)[..]);
    // 在Box调用deref, 再在String上调用deref
    do_something(x.deref().deref());
    // 等价
    do_something(&x);

    // 提前清理
    drop(x);

    println!("----");

    let a = Rc::new(Node::Cons(5, Rc::new(Node::Nil())));
    // b和c都持有a的所有权, Rc::clone() 只增加引用计数, 不执行深度拷贝
    // Rc<T> 通过不可变引用实现在程序不同部分共享只读数据
    let b = Node::Cons(1, Rc::clone(&a));
    let c = Node::Cons(2, Rc::clone(&a));

    // clone方法会执行深度拷贝
    // 也会增加引用计数
    let d: Rc<Node> = a.clone();

    // 返回引用计数
    println!("the ref cnt of a:{}", Rc::strong_count(&a));
}


